import {
  UPDATE_TODAY_NOTICE, UPDATE_DEALS_NOTICE, UPDATE_DEPTH_NOTICE,
  SET_SERVER_AUTH, UPDATE_PENDING_ORDER, UPDATE_HISTORY_ORDER
} from '@/constants/mutation-types'
import WS, { TYPES as wsConst } from '@/websocket'
export default function ({ store }, inject) {
  let socket
  let timerId
  let lockedReconnect = false // 避免重复连接

  function createWebSocket (wsUrl) {
    try {
      socket = new WS(wsUrl)
      initialize()
      inject('socket', socket)
    } catch (e) {
      console.log('catch')
    }
  }

  function reconnect () {
    if (lockedReconnect) { return }
    clearTimeout(timerId)
    timerId = setTimeout(function () {
      console.log('reconnecting')
      createWebSocket(store.state.initInfo.via_websocket_url)
      lockedReconnect = false
    }, 4000)
  }

  function initialize () {
    socket.onopen = function () {
      console.log('onopen: 连接成功')
      const { state } = store
      socket.subscribeToday(state.market.coinPairInfo)
      socket.ping()

      if (state.auth.userToken) {
        socket.auth({
          accessToken: state.auth.userToken,
          platform: state.platform
        })
      }
    }
    socket.onmessage = function (e) {
      const { method, params, result, id } = JSON.parse(e.data)
      const type = id || method
      switch (type) {
        case 'today.update':
          // 24小时行情
          store.commit(`market/${UPDATE_TODAY_NOTICE}`, { params })
          break
        case 'deals.update':
          store.commit(`exchange/${UPDATE_DEALS_NOTICE}`, { params })
          break
        case 'depth.update':
          store.commit(`exchange/${UPDATE_DEPTH_NOTICE}`, { params })
          break
        case wsConst.SERVER_AUTH_ID:
          if (!result) {
            // @notice: server认证不稳定
            socket.auth({
              accessToken: store.state.auth.userToken,
              platform: store.state.platform
            })
            store.commit(`exchange/${SET_SERVER_AUTH}`, false)
          } else {
            store.commit(`exchange/${SET_SERVER_AUTH}`, true)
            console.log('server auth ok')
          }
          break
        case wsConst.ORDER_QUERY_ID:
          console.log('order.query:', result)
          store.commit(`exchange/${UPDATE_PENDING_ORDER}`, result)
          break
        case wsConst.ORDER_HISTORY_ID:
          store.commit(`exchange/${UPDATE_HISTORY_ORDER}`, result)
          break
        case wsConst.PING:
          console.log(result)
          break
        default:
          break
      }
    }

    socket.onerror = function (event) {
      console.log('WebSocket error observed')
      reconnect()
      lockedReconnect = true
    }
    socket.onclose = function () {
      console.log('Websocket is closed.')
      reconnect()
      lockedReconnect = true
    }
  }

  if (store.state.initInfo.via_websocket_url) {
    createWebSocket(store.state.initInfo.via_websocket_url)
  }
  store.watch((state) => {
    return state.initInfo.via_websocket_url
  }, (wsUrl) => {
    createWebSocket(wsUrl)
  })
}
